---
title: Composants
description: Une introduction à la syntaxe des composants .astro.
i18nReady: true
---

**Les composants Astro** sont les blocs de base de tout projet Astro. Ce sont des composants avec seulement du HTML, sans exécution côté client. Vous pouvez repérer un composant Astro par son extension de fichier : `.astro`.

Les composants Astro sont extrêmement flexibles. Souvent, un composant Astro contiendra une **interface utilisateur réutilisable sur la page**, comme un en-tête ou une carte de profil. À d'autres moments, un composant Astro peut contenir un petit extrait de code HTML, comme une collection de balises `<meta>` courantes qui facilitent le travail avec le référencement. Les composants Astro peuvent même contenir la mise en page entière d'une page.

La chose la plus importante à savoir sur les composants Astro est qu'ils **ne sont pas rendus côté client**. Ils sont rendus en HTML soit au moment de la construction, soit à la demande en utilisant le [rendu côté serveur (SSR)](/fr/guides/server-side-rendering/). Vous pouvez inclure du code JavaScript à l'intérieur de votre composant, il sera entièrement supprimé de la page finale envoyée aux navigateurs de vos utilisateurs. Le résultat est un site plus rapide, sans aucune empreinte JavaScript ajoutée par défaut.

Lorsque votre composant Astro nécessite une interactivité côté client, vous pouvez ajouter des [balises HTML `<script>` standard](/fr/guides/client-side-scripts/) ou des [composants de Framework](/fr/guides/framework-components/#hydratation-des-composants-interactifs).


## Structure du composant

Un composant Astro est composé de deux parties principales : le **Script du composant** et le **Template du composant**. Chacune de ces parties s'occupe de faire une tâche différente, mais ensemble, constituent un cadre facile d'utilisation et assez expressif pour gérer tout ce que vous voulez construire.

```astro title="src/components/EmptyComponent.astro"
---
// Script du composant (JavaScript)
---
<!-- Template du composant (HTML + Expressions JS) -->
```

### Le Script du composant

Astro utilise des barres de code (`---`) pour identifier le script du composant dans votre composant Astro. Si vous avez déjà écrit du Markdown avant, vous pourriez être déjà familier avec un concept similaire appelé *frontmatter.* Astro est directement inspiré de cela.

Vous pouvez utiliser le script du composant pour écrire du code JavaScript qui vous aidera à construire votre template. Cela peut inclure :

- Importer d'autres composants Astro
- Importer des composants de Framework, comme React
- Importer des données, comme un fichier JSON
- Récupérer le contenu d'une API ou une base de données
- Créer des variables que vous voulez référencer dans votre template


```astro title="src/components/MyComponent.astro"
---
import SomeAstroComponent from '../components/SomeAstroComponent.astro';
import SomeReactComponent from '../components/SomeReactComponent.jsx';
import someData from '../data/pokemon.json';

// Accéder aux propriétés passées dans le composant, comme `<X title="Hello, World" />`
const {title} = Astro.props;
// Récupérer des données externes, même depuis une API privée ou une base de données
const data = await fetch('SOME_SECRET_API_URL/users').then(r => r.json());
---
<!-- Votre template ici ! -->
```

Les barres de code sont conçues pour garantir que le code JavaScript que vous écrivez à l'intérieur "ne puisse pas s'échapper". Ce code n'apparaîtra pas dans le code final de votre page et ne sera pas visible à vos utilisateur. Vous pouvez écrire du code JavaScript coûteux (en terme de performance) ou sensible (comme un appel à votre base de données privée) sans vous soucier qu'il se retrouve dans le navigateur l'utilisateur.

:::tip
Vous pouvez même écrire du TypeScript dans votre script de composant !
:::

### Le Template du composant

En dessous du script du composant se trouve le template du composant. Le template du composant détermine le HTML résultant de votre composant.

Si vous écrivez du HTML simple ici, votre composant affichera cet HTML dans toutes les pages où il est importé et utilisé.

De plus, la [syntaxe du template du composant Astro](/fr/basics/astro-syntax/) prend également en charge les **expressions JavaScript**, les balises [`<style>`](/fr/guides/styling/#styliser-avec-astro) et [`<script>`](/fr/guides/client-side-scripts/#utilisation-du-script-dans-astro) Astro, les **composants importés** et les [**directives spéciales Astro**](/fr/reference/directives-reference/). Les données et les valeurs définies (à la compilation) dans le script du composant peuvent être utilisées dans le template du composant pour produire du HTML dynamiquement créé.

```astro title="src/components/MyFavoritePokemon.astro"
---
// Votre script du composant ici !
import Banner from '../components/Banner.astro';
import ReactPokemonComponent from '../components/ReactPokemonComponent.jsx';
const myFavoritePokemon = [/* ... */];
const { title } = Astro.props;
---
<!-- les commentaires HTML sont supportés ! -->
{/* La syntaxe des commentaires JavaScipt est aussi valide ! */}

<Banner />
<h1>Hello, world!</h1>

<!-- Utilisez les propriétés et autres variables du script du composant : -->
<p>{title}</p>

<!-- Incluez d'autres composants avec une directive `client:` pour l'hydrater : -->
<ReactPokemonComponent client:visible />

<!-- Mixez du HTML avec des expressions JavaScript, similaire au JSX : -->
<ul>
  {myFavoritePokemon.map((data) => <li>{data.name}</li>)}
<ul>

<!-- Utilisez une directive de template pour créer des classes à partir de plusieurs chaînes ou même d'objets ! -->
<p class:list={["add", "dynamic", {classNames : true}]} />
```

## Conception à base de composant

Les composants sont conçus pour être **réutilisables** et **composables**. Vous pouvez utiliser des composants à l'intérieur d'autres composants pour créer une interface utilisateur de plus en plus complexe. Par exemple, un composant `Button` pourrait être utilisé pour créer un composant `ButtonGroup` comme ceci :

```astro title="src/components/ButtonGroup.astro"
---
import Button from './Button.astro';
---
<div>
  <Button title="Button 1" />
  <Button title="Button 2" />
  <Button title="Button 3" />
</div>
```


## Props de composant

Un composant Astro peut définir et accepter des "props". Ces props deviennent alors accessible dans le template du composant pour le rendu du HTML. Les props sont disponibles sur la variable globale `Astro.props` entre les barres de codes.

Voici un exemple de composant qui reçoit un prop nommé `greeting` et un prop nommé `name`. Notez que les props à recevoir sont déstructurés de l'objet global `Astro.props`.

```astro "Astro.props"
---
// src/components/GreetingHeadline.astro
// Utilisation: <GreetingHeadline greeting="Comment ça va" name="Partenaire" />
const { greeting, name } = Astro.props;
---
<h2>{greeting}, {name} !</h2>
```

Ce composant, lorsqu'il est importé et utilisé dans d'autres composants standards, Composants Layout ou pages Astro, peut recevoir ces props sous forme d'attributs :

```astro /(\w+)=\S+/
---
// src/components/GreetingCard.astro
import GreetingHeadline from './GreetingHeadline.astro';
const name = 'Astro';
---
<h1>Carte de bienvenue</h1>
<GreetingHeadline greeting="Salut" name={name} />
<p>J'espère que vous passez une merveilleuse journée !</p>
```

Vous pouvez également définir le type de vos props avec TypeScript en créant une interface nommée `Props`. Astro sélectionnera automatiquement l'interface `Props` dans le Script du Composant et donnera des avertissements/erreurs de type. Ces props peuvent également recevoir des valeurs par défaut lorsqu'ils sont déstructurés à partir d' `Astro.props`.

```astro ins={3-6}
---
// src/components/GreetingHeadline.astro
interface Props {
  name: string;
  greeting?: string;
}

const { greeting = "Salut", name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>
```

Les props de composant peuvent recevoir des valeurs par défaut à utiliser lorsqu'aucune n'est fournie

```astro ins="= \"Salut\"" ins="= \"Astronaute\""
---
// src/components/GreetingHeadline.astro
const { greeting = "Salut", name = "Astronaute" } = Astro.props;
---
<h2>{greeting}, {name}!</h2>
```

## Les emplacements (slots)

L'élément `<slot />` est un emplacement réservé pour du contenu HTML externe, vous permettant d'injecter des éléments enfants depuis d'autres fichiers, dans le template de votre composant.

Par défaut, tous les éléments enfants passés à un composant seront rendus dans son `<slot />`.

:::note
Contrairement aux *props*, qui sont des attributs passés à un composant Astro disponibles pour une utilisation dans votre composant avec `Astro.props`, _les emplacements_ restituent les éléments HTML enfants là où ils sont placés.
:::

```astro "<slot />"
---
// src/components/Wrapper.astro
import Header from './Header.astro';
import Logo from './Logo.astro';
import Footer from './Footer.astro';

const { title } = Astro.props;
---
<div id="content-wrapper">
  <Header />
  <Logo />
  <h1>{title}</h1>
  <slot /> <!-- les élement enfants seront insérés ici -->
  <Footer />
</div>
```

```astro {6-7}
---
// src/pages/fred.astro
import Wrapper from '../components/Wrapper.astro';
---
<Wrapper title="Page de Fred">
  <h2>Tout ce qui est a savoir sur Fred</h2>
  <p>Voici quelques truc à propos de Fred.</p>
</Wrapper>
```

Ce modèle est la base d'un [Composant Layout dans Astro](/fr/basics/layouts/) : une page entière de contenu HTML peut être "enveloppée" avec des balises `<Layout></Layout>` et envoyée au composant pour être rendue à l'intérieur des éléments de page communs qui y sont définis.



### Les emplacements (slots) nommés

Un composant Astro peut aussi avoir des emplacements nommés. Cela vous permet de ne faire passer que des éléments HTML avec le nom d'emplacement (slot) correspondant, au niveau de l'emplacement.

Les emplacements (slots) sont nommés à l'aide de l'attribut `name` :

```astro /<slot.*?/>/
---
// src/components/Wrapper.astro
import Header from './Header.astro';
import Logo from './Logo.astro';
import Footer from './Footer.astro';

const { title } = Astro.props;
---
<div id="content-wrapper">
<Header />
<slot name="after-header" /> <!-- les enfants avec l'attribut `slot="after-header" iront ici  -->
<Logo />
<h1>{title}</h1>
<slot /> <!-- les enfants sans `slot` ou avec l'attribut `slot="default"`iront ici -->
<Footer />
<slot name="after-footer" /> <!-- les enfants avec l'attribut `slot="after-footer"` iront ici -->
</div>
```

Pour injecter du contenu HTML dans un emplacement (slot) particulier, utilisez l'attribut `slot` sur n'importe quel élément enfant pour spécifier le nom de l'emplacement (slot). Tous les autres éléments enfants du composant seront injectés dans le `<slot />` par défaut (sans nom).


```astro /slot=".*?"/
---
// src/pages/fred.astro
import Wrapper from '../components/Wrapper.astro';
---
<Wrapper title="Page de Fred">
  <img src="https://my.photo/fred.jpg" slot="after-header" />
  <h2>Tout ce qui est a savoir sur Fred</h2>
  <p>Voici quelques truc à propos de Fred.</p>
  <p slot="after-footer">Copyright 2022</p>
</Wrapper>
```

:::tip
Utilisez un attribut `slot="my-slot"` sur l'élément enfant que vous voulez passer à un emplacement correspondant `<slot name="my-slot" />` dans votre composant.
:::

Pour faire passer plusieurs éléments HTML dans l'espace réservé `<slot/>` d'un composant sans qu'ils soient enveloppés par un `<div>`, utilisez l'attribut `slot=""` sur le [composant `<Fragment/>` d'Astro](/fr/reference/api-reference/#fragment-):

```astro title="src/components/CustomTable.astro" "<slot name="header"/>" "<slot name="body" />"
---
// Créer un tableau personnalisé avec des emplacements (slot) nommés pour le contenu HEAD et BODY du contenu.
---
<table class="bg-white">
  <thead class="sticky top-0 bg-white"><slot name="header" /></thead>
  <tbody class="[&_tr:nth-child(odd)]:bg-gray-100"><slot name="body" /></tbody>
</table>
```

Injecter plusieurs lignes et colonnes de contenu HTML en utilisant un attribut `slot=""` pour spécifier le contenu `"header"` et `"body"`. Les éléments HTML individuels peuvent également être stylisés :

```astro title="src/components/StockTable.astro" {5-7, 9-13} '<Fragment slot="header">' '<Fragment slot="body">'
---
import CustomTable from './CustomTable.astro';
---
<CustomTable>
  <Fragment slot="header"> <!-- pass table header -->
    <tr><th>Nom du produit</th><th>Unités en stock</th></tr>
  </Fragment>

  <Fragment slot="body"> <!-- pass table body -->
    <tr><td>Tongs</td><td>64</td></tr>
    <tr><td>Bottes</td><td>32</td></tr>
    <tr><td>Baskets</td><td class="text-red-500">0</td></tr>
  </Fragment>
</CustomTable>
```

Notez que les emplacements nommés doivent être des enfants immédiats du composant. Il n'est pas possible de faire passer des emplacements nommés dans des éléments imbriqués.

:::tip
Les emplacements nommés peuvent aussi être passés aux [composants de framework](/fr/guides/framework-components/) !
:::


:::note
Il n'est pas possible de générer dynamiquement un nom de slot Astro, par exemple dans une fonction de carte. Si cette fonctionnalité est nécessaire dans les composants du framework UI, il est préférable de générer ces slots dynamiques dans le framework lui-même.
:::


### Contenu par défaut pour les emplacements
La génération dynamique d'un nom de slot Astro, par exemple dans une fonction map, a été ajoutée dans Astro v4.2.0. Pour les versions antérieures d'Astro, il est préférable de générer ces slots dynamiques dans le cadre lui-même.

```astro {14}
---
// src/components/Wrapper.astro
import Header from './Header.astro';
import Logo from './Logo.astro';
import Footer from './Footer.astro';

const { title } = Astro.props;
---
<div id="content-wrapper">
  <Header />
  <Logo />
  <h1>{title}</h1>
  <slot>
    <p>Ceci est mon contenu par defaut, s'il n'y a pas d'enfants passés à l'emplacement</p>
  </slot>
  <Footer />
</div>
```

### Transférer les emplacements

Les emplacements peuvent être transférés à d'autres composants. Par exemple, lorsque l'on crée des mises en page imbriquées :

```astro title="src/layouts/BaseLayout.astro" {9,12}
---
---
<html lang="fr">
	<head>
		<meta charset="utf-8" />
		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="viewport" content="width=device-width" />
		<meta name="generator" content={Astro.generator} />
    <slot name="head" />
	</head>
	<body>
		<slot />
	</body>
</html>
```

```astro {6,7}
// src/layouts/HomeLayout.astro
---
import BaseLayout from './BaseLayout.astro';
---
<BaseLayout>
  <slot name="head" slot="head" />
  <slot />
</BaseLayout>
```

:::note
Les emplacements nommés peuvent être transférés vers un autre composant en utilisant les attributs `name` et `slot` sur une balise `<slot />`.
:::

Maintenant, les emplacements par défaut et `head` passés à `HomeLayout` seront transférés au parent `BaseLayout`.

```astro
// src/pages/index.astro
---
import HomeLayout from '../layouts/HomeLayout.astro';
---
<HomeLayout>
	<title slot="head">Astro</title>
	<h1>Astro</h1>
</HomeLayout>
```


## Composants HTML

Astro prend en charge l'importation et l'utilisation de fichiers `.html` en tant que composants ou le placement de ces fichiers dans le sous-répertoire `src/pages` en tant que pages. Vous souhaiterez peut-être utiliser des composants HTML si vous réutilisez le code d'un site existant construit sans framework, ou si vous voulez vous assurer que votre composant n'ai pas de fonctionnalités dynamiques.

Les composants HTML ne doivent contenir que du code HTML valide et ne disposent donc pas des fonctionnalités clés des composants Astro :
- Ils ne prennent pas en charge de Script de Composant, les importations côté serveur ou les expressions dynamiques.
- Toutes les balises `<script>` sont laissées non regroupées, traitées comme si elles avaient `is:inline`.
- Ils ne peuvent [référencer que les assets qui se trouvent dans le dossier `public/`](/fr/basics/project-structure/#public).

:::note
Un [élément `<slot />`](#les-emplacements-slots) à l'intérieur d'un composant HTML fonctionnera comme il le ferait dans un composant Astro. Pour utiliser l'élément [Slot des Web Components (composants web)](https://developer.mozilla.org/fr/docs/Web/HTML/Element/slot)  à la place, ajoutez `is:inline` à votre élément `<slot>`.
:::
## Étapes suivantes

import ReadMore from '~/components/ReadMore.astro';

<ReadMore>Apprendre comment utiliser les [composants de framework JavaScript](/fr/guides/framework-components/) dans votre projet Astro.</ReadMore>
